<template>
	<div>
		<!-- 面包屑导航区 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
		  <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
		  <el-breadcrumb-item>角色管理</el-breadcrumb-item>
		  <el-breadcrumb-item>角色列表</el-breadcrumb-item>
		</el-breadcrumb>
		
		<!-- 卡片视图 -->
		<el-card>
			<!-- 添加角色按钮 -->
			<el-row>
				<el-col><el-button type="primary" @click="addDialogRoles=true">添加角色</el-button></el-col>
			</el-row>
			
			<el-table :data="rolelist" border stripe>
					<!-- 展开列表 -->
					<el-table-column type="expand">
						<!-- slot-scope="scope" 来取得作用域插槽:data绑定的数据，scope可以随便替换其他名称，只是定义对象来代表取得的data数据，便于使用 -->
						<template slot-scope="scope">
							<el-row :class="['bdbottom',i1===0 ?'bdtop':'','vcenter']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
								<!-- 渲染一级权限 -->
								<el-col :span="5">
									<el-tag @close="removeRightByid(scope.row,item1.id)">{{item1.authName}}</el-tag>
									<i class="el-icon-caret-right"></i>
								</el-col>
								<!-- 渲染二级和三级权限 -->
								<el-col :span="19">
									<el-row :class="[i2===0?'':'bdtop','vcenter']" v-for="(item2, i2) in item1.children" :key="item2.id">
										<el-col :span="6">
											<el-tag type="success"  closable @close="removeRightByid(scope.row,item2.id)">{{item2.authName}}</el-tag>
											<i class="el-icon-caret-right"></i>
										</el-col>
										<el-col :span="18">
											<el-tag type="warning" v-for="(item3,i3) in item2.children" :key="item3.id" closable @close="removeRightByid(scope.row,item3.id)">
												{{item3.authName}}
											</el-tag>
										</el-col>
									</el-row>
								</el-col>
							</el-row>
							<!-- {{scope.row}} -->
						</template>
					</el-table-column>
					<el-table-column label="角色名称" prop="roleName"></el-table-column>
					<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
					<el-table-column label="操作"  width="300px">
						<template v-slot="scope">
							<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">编辑</el-button>
							<el-button size="mini" type="danger" icon="el-icon-delete" @click="removeRolesById(scope.row.id)" >删除</el-button>
							<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配权限</el-button>	
						</template>
					</el-table-column>
			</el-table>
		</el-card>
		
		<!-- 添加角色对话框 -->
		<el-dialog title="添加角色" :visible.sync="addDialogRoles" width="50%" @close="addDialogClosed">
			<!-- 内容主体区域 -->
			<el-form :model="addForm" ref="addFormRef" label-width="70px">
				<el-form-item label="角色名称" prop="roleName">
				  <el-input v-model="addForm.roleName"></el-input>
				</el-form-item>
				<el-form-item label="角色描述" prop="roleDesc">
				  <el-input v-model="addForm.roleDesc"></el-input>
				</el-form-item>			
			</el-form>
			<!-- 底部区域 -->
				<span slot="footer" class="dialog-footer">
					<el-button @click="addDialogRoles = false">取 消</el-button>
					<el-button type="primary" @click="addRoles">确 定</el-button>
				</span>
			
		</el-dialog>
		
		<!-- 编辑角色对话框 -->
		<el-dialog title="修改角色" :visible.sync="editDialogRoles" width="50%" @close="editDialogClosed">
			<el-form :model="editForm" ref="editFormRef" label-width="70px" >
				<el-form-item label="角色名称" >
				  <el-input v-model="editForm.roleName" ></el-input>
				</el-form-item>
				<el-form-item label="角色描述" >
				  <el-input v-model="editForm.roleDesc" ></el-input>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button @click="editDialogRoles=false">取消</el-button>
				<el-button type="primary" @click="editRolesInfo">确定</el-button>
			</span>
		</el-dialog>
		
		<!-- 分配权限对话框 -->
		<el-dialog
		  title="提示"
		  :visible.sync="setRightDialogVisible"
		  width="50%" @close="setRightDialogClosed" >
		  <!-- 树形控件 -->
		  <el-tree :data="rightslist" :props="treeProps" show-checkbox node-key="id" default-expand-all :default-checked-keys="defKeys"  ref="treeRef"></el-tree>
		  <span slot="footer" class="dialog-footer">
		    <el-button @click="setRightDialogVisible = false">取 消</el-button>
		    <el-button type="primary"  @click="allotRights">确 定</el-button>
		  </span>
		</el-dialog>
	</div>
</template>

<script>
export default{
	data() {
		return{
			// 所以角色列表数据
			rolelist:[],
			// 添加角色表单数据
			addForm:{
				roleName:'',
				roleDesc:''				
			},
			// 查询到用户信息对象
			editForm:{},
			// 所以权限数据
			rightslist:[],
			// 树形控件属性绑定对象
			treeProps:{
				label:'authName',
				children:'children'
			},
			// 默认选择节点id
			defKeys:[],
			// 当前即将分配权限的角色id
			roloId:'',
			// 对话框的隐藏显示
			addDialogRoles:false,
			editDialogRoles:false,
			setRightDialogVisible:false,
			
			
		}
	},
	created() {
		this.getRolesList()
	},
	methods:{
		// 获取所以角色列表
		async getRolesList(){
			const {data : res}=await this.$http.get('http://127.0.0.1:8888/api/private/v1/roles')
			if(res.meta.status !==200){
				return this.$message.error('获取角色列表失败')
			}
			this.rolelist=res.data
			console.log(this.rolelist)
		},
		// 监听添加用户对话框关闭事件
		addDialogClosed(){
			this.$refs.addFormRef.resetFields()
		},
		// 点击按钮,添加角色
		addRoles(){
			this.$refs.addFormRef.validate(async valid=>{
				if(!valid) return
				// 可以添加网络请求
				const {data: res}= await this.$http.post("http://127.0.0.1:8888/api/private/v1/roles", this.addForm)
				if(res.meta.status!=201){
					this.$message.error("添加角色失败")
					
				}
				this.$message.success('添加用户成功')
				// 隐藏添加角色对话框
				this.addDialogRoles=false
				// 重获取角色列表数据
				this.getRolesList()
			})		
		},
		// 展示编辑角色的对话框
		async showEditDialog(id){
			const{data:res}= await this.$http.get('http://127.0.0.1:8888/api/private/v1/roles/'+id)
			if(res.meta.status!==200){
				return this.$message.error('查询角色失败')
			}
			this.editForm=res.data
			this.editDialogRoles=true
		},
		// 监听编辑用户对话框关闭
		editDialogClosed(){
			this.$refs.editFormRef.resetFields()
		},
		// 修改用户信息并提交
		editRolesInfo(){
			this.$refs.editFormRef.validate(async valid=>{
				if(!valid) return
				// 发起修改用户信息请求
				const {data:res} =await this.$http.put('http://127.0.0.1:8888/api/private/v1/roles/'+this.editForm.roleId,
				{roleName:this.editForm.roleName,
				roleDesc:this.editForm.roleDesc,
				})
				if(res.meta.status!==200){
					return this.$message.error('更新角色信息失败')
				}
				// 关闭对话框
				this.editDialogRoles=false
				// 刷新数据表
				this.getRolesList()
				// 提示修改成功
				this.$message.success('更新用户信息成功！')
			})
		},
		// 根据id删除数据
		async removeRolesById(id){
			// 弹出操作咨询用户是否删除角色
			const confirmResult=await this.$confirm('此操作将永久删除该角色,是否继续？','提升',{
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).catch(err=>err)
			// 如果用户确删除，返回字符串为confirm
			// 如果用户取消删除，返回字符串cancel
			if(confirmResult !=='confirm'){
				return this.$message.info('已经取消删除')
			}
			const {data:res}=await this.$http.delete('http://127.0.0.1:8888/api/private/v1/roles/'+ id)
			if(res.meta.status!==200){
				return this.$message.error('删除角色失败')
			}
			// 提示修改成功
			this.$message.success('删除角色成功')
			// 刷新数据列表
			this.getRolesList()
		},
		
		// 根据id删除对于权限
		async removeRightByid(role,rightId){
			// 弹框提示是否要删除
			 const confirmResult =await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
			          confirmButtonText: '确定',
			          cancelButtonText: '取消',
			          type: 'warning'
			}).catch(err=> err)
			
			if(confirmResult!=='confirm'){
				return this.$message.info('取消删除！')
			}
			const {data:res} = await this.$http.delete(`http://127.0.0.1:8888/api/private/v1/roles/${role.id}/rights/${rightId}`)
			if(res.meta.status !== 200){
				return this.$message.error('删除权限失败')
			}
			role.children =res.data
			// this.getRolesList()
		},
		// 展示分配权限的对话框
		async showSetRightDialog(role){
			this.roloId=role.id
			// 获取所以权限数据
			 const {data:res}=await this.$http.get('http://127.0.0.1:8888/api/private/v1/rights/tree')
			 if(res.meta.status!==200){
				 return this.$message.error('获取权限数据失败')
			 }
			 // 获取到的权限数据保存到data中
			 this.rightslist=res.data
			 console.log(this.rightslist)
			// 递归获取三级节点id
			this.getLeafKeys(role,this.defKeys)
			this.setRightDialogVisible=true
		},
		// 通过递归，获取角色下所以三级权限id 并保存defkeys数组中
		getLeafKeys(node,arr){
			// 如果当前node节点不包含children属性 则是三级节点
			if(!node.children){
				return arr.push(node.id)
			}
			node.children.forEach(item=>this.getLeafKeys(item,arr))
			
		},
		// 监听分配对话框的关闭事件
		setRightDialogClosed(){
				this.defKeys=[]
		},
		// 点击为角色分配权限
		async allotRights(){
			const keys = [
				...this.$refs.treeRef.getCheckedKeys(),
				...this.$refs.treeRef.getHalfCheckedKeys()
			]
			const idStr =keys.join(',')
			const {data:res}=await this.$http.post(`http://127.0.0.1:8888/api/private/v1/roles/${this.roloId}/rights`,{rids:idStr})
			if(res.meta.status!==200){
				return this.$message.error('分配权限失败！')
			}
			
			this.$message.success('分配权限成功')
			this.getRolesList()
			this.setRightDialogVisible=false
		}	
		
	
	}
	

	
}
</script>

<style lang="less" scoped>
.el-tag{
	margin: 7px;
}
.bdtop{
	border-top: 1px solid #eee;
}
.bdbottom{
	border-bottom: 1px solid #eee;
}
.vcenter{
	display: flex;
	align-items: center;
}

</style>
